parser grammar CParser;

options {
  language = Java;
  tokenVocab = CLexer;
}


@header {
  package ejercicio4;
  //import java.util.HashMap;
}

@members {
      //Lista que guarda los errores que se van produciendo durante el analisis lexico
    List<RecognitionException> errors = new ArrayList<RecognitionException>();

    //Metodo que devuelve la lista de errores que se han producido
    public List<RecognitionException> getAllErrors() {
        return errors;
    }
    
    //Metodo que comprueba si se han producido errores
    public boolean hasErrors() {
        return !errors.isEmpty();
    }

    //Metodo del analizador lexico sobrescrito para que los errores que se van
    //produciendo durante el analisis lexico en vez de mostrarse por consola
    //se guarden en la lista de errores (errors)
    @Override
    public void reportError(RecognitionException e) {
        errors.add(e);
    }
    //HashMap memory = new HashMap();
    String buffer = "";
}

entrada: funcion EOF;

funcion returns[String cad] : tipo IDENT  parametros?   cuerpo 
          // {System.out.println("Funcion:\n " +$funcion.text);}
          {$cad = $tipo.text + " "+ $IDENT.text + $parametros.text + "{\n" + $cuerpo.cad + "}"; 
          System.out.println("Codigo: \n"+$cad);}
          ;

cuerpo returns[String cad] : LLAVES interior_funcion LLAVES
                            {$cad =  $interior_funcion.cad;} ;
             
               

interior_funcion returns[String cad] : decl_variables
               {$cad =  $decl_variables.cad;} 
               sentencia_if
               {$cad =  $cad+$sentencia_if.cad;}
               ;
sentencia_if returns[String cad] : IF  condicion  cuerpo_if+ 
                                  {$cad = $IF.text + $condicion.text +"{\n"+ $cuerpo_if.cad +"}\n";}
                                  ;
 
condicion : PARENTESIS (IDENT | exp) COMPARADORES LETRA PARENTESIS;

exp : NUMERO OPERADORES LETRA;

cuerpo_if returns[String cad] : LLAVES interior_if LLAVES
                                 {$cad = $interior_if.cad;}
                                 ;
                                 
interior_if returns[String cad] : llamada_funcion
                                  {$cad = $llamada_funcion.cad;}     
                                  asignacion
                                  {$cad = $cad + $asignacion.cad;}
                                   ;
llamada_funcion returns[String cad] : IDENT  parametros  SEPARADOR 
                                     { $cad = $llamada_funcion.text;
                                       $cad = $cad.replace("\r\n", "");
                                       $cad = $cad + "\n";
                                      }
                                      ;

decl_variables returns[String cad] : tipo (COMA? LETRA)+ SEPARADOR
                              {$cad = $decl_variables.text + "\n";}
                              ;  

tipo : VOID | INT;

parametros : PARENTESIS interior_param PARENTESIS ;

interior_param : (VOID | (COMA? (CADENA | LETRA))+ );

asignacion returns[String cad] : LETRA IGUAL LETRA OPERADORES NUMERO SEPARADOR
              { $cad = $asignacion.text + "\n";}
              ;
                                


